﻿
using KinectWindowLib.Graphics;
using KinectWindowLib.Windows;
using KinectWindows;
using KinectWindows.Math;
using KinectWindows.Windows;
using SharpGL;
using SharpGL.SceneGraph;
using SharpGL.SceneGraph.Cameras;
using SharpGL.SceneGraph.Effects;
using SharpGL.SceneGraph.Helpers;
using SharpGL.SceneGraph.Lighting;
using SharpGL.SceneGraph.Primitives;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SharpGLWinformsApplication1;
using KinectWindowLib.NuiControls;

namespace KinectWindowLib
{
    // The main Display That all the visyal Elements will be placed in
    // It conian One Or more Screens
    public static class Display
    {
        public static Stack<NuiWindow> WindowStack = new Stack<NuiWindow>();
        private static List<Screen> Screens = new List<Screen>();
        public static OpenGL GL { get; set; }
        public static int Height { get; set; }
        public static int Width { get; set; } 
        public static void CreatDisplay(OpenGL gl)
        { 
             Display.GL = gl;
               
        }
        public static void CreatDisplay(OpenGL gl,int Width,int Height)
        {
            Display.Height = Height;
            Display.Width = Width;
            Display.CreatDisplay(gl);
           

        }
        public static Colormap GetDisplayColorMap()
        {
            Colormap map = new Colormap();
            return map;
        }
        public static GraphicContext DefaultGC()
        {
            GraphicContext gc = Display.GetDefaultScreen().GC;
            return gc;
        }
        public static NuiWindow DefaultRootWindow()
        {
            return WindowStack.ToArray()[WindowStack.Count-1];
        }
        public static void AddScreen(Screen scr)
        {
            scr.Id = Screens.Count;
            scr.SetBounds(Display.Width, Display.Height);            
            Screens.Add(scr);
        }
        public static Screen GetDefaultScreen()
        {
            return Screens[0];
        }
        public static void Unregesterwindow(NuiWindow wind)
        {
            
            NuiWindow[] winCol = WindowStack.ToArray();
            List<NuiWindow> win_col = new List<NuiWindow>();
            WindowStack = new Stack<NuiWindow>();
            for (int i = 0; i < winCol.Length; i++) if (winCol[i].Id != wind.Id) win_col.Add(winCol[i]);
            WindowStack.Clear();
            for (int i = win_col.Count; i > 0; i--) WindowStack.Push(win_col[i]);
           
        }
        public static void Regesterwindow(NuiWindow nui)
        {
            WindowStack.Push(nui);
        }

  
        public static void DistroyWindow(NuiWindow wind)
        {
            NuiEventManager.PostEvent(new NuiEvent(KinectWindows.WindowMessages.NUI_MSG_WINDOW_DISTROY, null));
            Display.Unregesterwindow(wind);
            NuiEventManager.PostEvent(new NuiEvent(KinectWindows.WindowMessages.NUI_MSG_WINDOW_DISTROYED, null));


        }
        public static NuiWindow CreateSimpleWindow(NuiWindow parent, Vector2 Location, Vector2 Dimentions)
        {

            WindowAttribute attr = new WindowAttribute();
            attr.Location = Location;
            attr.Dimentions = Dimentions;
            attr.Class = WindowClass.WC_SIMPLE_WINDOW;
            attr.Boarder_width = 1;
            attr.Show_Titile_bar = true;
            attr.Show_Status_bar = true;

            return Display.CreateWindow(parent, attr);
        }
        public static NuiWindow CreateRootWindow(Screen screen)
        {

            WindowAttribute attr = new WindowAttribute();
            attr.Location = Vector2.Zero;
            attr.Dimentions = new Vector2((float)screen.Width, (float)screen.Height);
            attr.Class = WindowClass.WC_ROOT;
            attr.Boarder_width = 0;
            attr.Show_Titile_bar = false;
            attr.Show_Status_bar = false;
            attr.ParentId = 0;
            attr.BackGroundColor = Color.White;

            return Display.CreateWindow(null, attr);
        }
        public static NuiWindow CreateDialogBox(NuiWindow parent, Vector2 Location, Vector2 Dimentions)
        {
            WindowAttribute attr = new WindowAttribute();
            attr.Location = Location;
            attr.Dimentions = Dimentions;
            attr.Class = WindowClass.WC_DIALOG_BOX;
            attr.Boarder_width = 1;
            attr.Show_Titile_bar = false;
            attr.Show_Status_bar = false;


            return Display.CreateWindow(parent, attr);
        }
        public static NuiWindow CreateWindow(NuiWindow parent, WindowAttribute attr)
        {
            GraphicContext gc = new GraphicContext();

            NuiWindow nui = new NuiWindow();
            nui.WindowAttributes = attr;
            nui.GCContext = Display.DefaultGC();
            attr.Parent = parent;/// this is the desktop window no Other root is presnr
            Display.Regesterwindow(nui);
            return nui;
        }
        public static NuiWindow MoveWindow(NuiWindow wind, Vector2 Direction)
        {
            Vector2 ParentPos = wind.getParent().Location;
            wind.SetLocation(ParentPos + wind.Location + Direction);
            NuiEventManager.PostEvent(new NuiEvent(WindowMessages.NUI_MSG_WINDOW_MOVED, new Object[] { wind }));
            return wind;
        }
        public static NuiWindow ResizeWindow(NuiWindow wind, Vector2 Scale)
        {
            wind.SetSize(Scale);
            NuiEventManager.PostEvent(new NuiEvent(WindowMessages.NUI_MSG_WINDOW_CHANGE_SIZE, new Object[] { wind }));
            return wind;
        }
        public static NuiWindow MoveResizeWindow(NuiWindow wind, Vector2 Direction, Vector2 Scale)
        {
            return ResizeWindow(MoveWindow(wind, Direction), Scale);
        }
        public static NuiWindow SetBoarderWidth(NuiWindow wind, int width)
        {
            wind.SetBoarderWidth(width);
            return wind;
        }
        public static void PushWindowUp(NuiWindow wind)
        {
        }
        public static void PushWindowDown(NuiWindow wind)
        {
        }
        public static void PushWindowFirst(NuiWindow wind)
        {
        }
        public static void PushWindowLast(NuiWindow wind)
        {
        }
        public static void SetCursor(long windId, NuiCursor curser)
        {
            List<NuiWindow> tem_stack = Display.WindowStack.ToList();
            for (int i = 0; i<tem_stack.Count; i++)
                if (tem_stack[i].Id == windId)
                    tem_stack[i].SetCurser(curser);
            ListToStack(tem_stack);

        }
        public static List<NuiWidget> getWindowChildren(NuiWindow wind)
        {
            return wind.Children;
        }
        public static WindowAttribute getWindowAttributes(NuiWindow wind)
        {
            return wind.WindowAttributes;
        }
        public static Pixmap CreatePixmap(Vector2 Dimention, int depth)
        {
            Pixmap pix = new Pixmap();
            pix.SetSize(Dimention);
            pix.Depth = depth;
            return pix;

        }
        public static void FillRectangle(Vector2 Postion, Vector2 Size, Color Fill)
        {
            GraphicContext gc = Display.GetDefaultScreen().GC;
            gc.DrawRectangle(Postion.X, Postion.Y, Size.X, Size.Y,Fill);
           
        }
        public static void ClearWindow(NuiWindow wind)
        {
            Display.DefaultGC().Clear(wind.WindowAttributes.Location,wind.WindowAttributes.Dimentions);
            NuiEventManager.PostEvent(new NuiEvent(WindowMessages.NUI_MSG_REPAINT,new Object[]{wind}));
        }
        public static void ClearWindow(NuiWindow wind,Color Fill)
        {
            Display.DefaultGC().Clear(wind.WindowAttributes.Location, wind.WindowAttributes.Dimentions,Fill);
            NuiEventManager.PostEvent(new NuiEvent(WindowMessages.NUI_MSG_REPAINT, new Object[] { wind }));
        }
        public static void DrawWindow(NuiWindow wind,int ZOrder)
        {
            wind.ZOrder = ZOrder;
            wind.Paint();
            NuiEventManager.PostEvent(new NuiEvent(WindowMessages.NUI_MSG_WINDOW_REPAINTED, new Object[] { wind }));
        }
        public static void SetFocus(NuiWindow wind)
        {
            PushWindowFirst(wind);
            wind.SetFocus();
            NuiEventManager.PostEvent(new NuiEvent(WindowMessages.NUI_MSG_WINDOW_HAS_FOCUS, new Object[] { wind }));
        }
        public static void LostFocus(NuiWindow wind)
        {
            PushWindowDown(wind);
            wind.LostFocus();
            NuiEventManager.PostEvent(new NuiEvent(WindowMessages.NUI_MSG_WINDOW_LOST_FOCUS, new Object[] { wind }));
        }
        private static void ListToStack(List<NuiWindow> list)
        {

            Display.WindowStack.Clear();
            for (int i = list.Count - 1; i >= 0; i--)
            {
                Display.WindowStack.Push(list[i]);
            }
            
        }




        public static void Refresh()
        {
           
            Display.GetDefaultScreen().GL_Scene.Draw();
            NuiEventManager.PostEvent(NuiEvent.Refresh);
        }

        public static void ClearDisplay()
        {
             Display.GetDefaultScreen().Clear();
        }
    }
   
   
}
